Почему определенные случайные строки дают цвета при вводе в качестве цветов фона в HTML? Например: тест ... создает документ с красным фоном во всех браузерах и платформах. Интересно, что в то время как Чакнорри также создает красный фон, Чакнорр создает желтый фон. Что тут происходит?
2020-12-07 21:57:30
Это пережиток времен Netscape: Отсутствующие цифры обрабатываются как 0 [...]. Неправильная цифра просто интерпретируется как 0. Например, значения # F0F0F0, F0F0F0, F0F0F, #FxFxFx и FxFxFx одинаковы. Это из сообщения в блоге Небольшая напыщенная речь о синтаксическом анализе цвета Microsoft Internet Explorer, который подробно описывает его, включая различную длину значений цвета и т. Если применить правила по очереди из сообщения в блоге, мы получим следующее: Замените все недопустимые шестнадцатеричные символы на 0: Чакноррис становится c00c0000000 Дополните до следующего общего количества символов, кратного 3 (11 → 12): c00c 0000 0000 Разделитесь на три равные группы, каждый компонент представляет соответствующий компонент цвета RGB: RGB (c00c, 0000, 0000) Обрежьте каждый аргумент справа до двух символов. Что в итоге дает следующий результат: RGB (c0, 00, 00) = # C00000 или RGB (192, 0, 0) Вот пример, демонстрирующий атрибут bgcolor в действии для создания этого «удивительного» образца цвета: <таблица>Чак Норрис Мистер Т черепаха-ниндзя Это также отвечает на другую часть вопроса: почему bgcolor = "chucknorr" дает желтый цвет? Что ж, если мы применим правила, строка будет такой: c00c00000 => c00 c00 000 => c0 c0 00 [RGB (192, 192, 0)] Что дает светло-желто-золотой цвет. Поскольку строка начинается с 9 символов, на этот раз мы сохраняем вторую букву «C», поэтому она заканчивается окончательным значением цвета. Первоначально я столкнулся с этим, когда кто-то указал, что можно сделать color = "дерьмо", и, ну, получается коричневый цвет. | Извините, что не согласен, но в соответствии с правилами анализа устаревшего значения цвета, опубликованными @Yuhong Bao, chucknorris НЕ приравнивается к # CC0000, а скорее к # C00000, очень похожему, но немного другому оттенку красного. Я использовал надстройку Firefox ColorZilla, чтобы проверить это. Правила гласят: сделайте длину строки кратной 3, добавив нули: chucknorris0 разделите нить на 3 нити равной длины: chuc knor ris0 обрезать каждую строку до 2 символов: ch kn ri сохраните шестнадцатеричные значения и при необходимости добавьте 0: C0 00 00 Я смог использовать эти правила для правильной интерпретации следующих строк: LuckyCharms Удача Удача УдачаBeALadyTonight Гангам стайл ОБНОВЛЕНИЕ: первоначальные ответчики, которые сказали, что цвет был # CC0000, с тех пор отредактировали свои ответы, чтобы включить исправление. | Большинство браузеров просто игнорируют любые НЕ-шестнадцатеричные значения в вашей цветовой строке, заменяя не-шестнадцатеричные цифры нулями. ChuCknorris переводится как c00c0000000. На этом этапе браузер разделит строку на три равные части, указав значения красного, зеленого и синего: c00c 0000 0000. Дополнительные биты в каждом разделе будут проигнорированы, что приведет к окончательному результату # c00000, который имеет красноватый цвет. Обратите внимание, это не относится к синтаксическому анализу цвета CSS, который соответствует стандарту CSS. больной хрень трава Красноватый
То же, что и выше
Черный
| Причина в том, что браузер не может это понять и пытается как-то перевести в то, что он может понять, и в данном случае в шестнадцатеричное значение! ... chucknorris начинается с c, который является распознанным символом в шестнадцатеричном формате, а также преобразует все нераспознанные символы в 0! Итак, chucknorris в шестнадцатеричном формате становится: c00c00000000, все остальные символы становятся 0, а c остается на месте ... Теперь они делятся на 3 для RGB (красный, зеленый, синий) ... R: c00c, G: 0000, B: 0000 ... Но мы знаем, что допустимый шестнадцатеричный для RGB - это всего 2 символа, то есть R: c0, G: 00, B: 00. Итак, реальный результат: bgcolor = "# c00000"; Я также добавил шаги на изображении в качестве краткого справочника для вас: | Браузер пытается преобразовать код чакнорриса в шестнадцатеричный цветовой код, потому что это недопустимое значение. В chucknorris все, кроме c, не является допустимым шестнадцатеричным значением. Таким образом, он преобразуется в c00c00000000. Что становится # c00000, оттенком красного. Похоже, это проблема в первую очередь Internet Explorer и Opera (12), так как Chrome (31) и Firefox (26) просто игнорируют это. P.S. Цифры в скобках - это версии браузеров, в которых я тестировал. На более легкой ноте Чак Норрис не соответствует веб-стандартам. Веб-стандарты соответствуют ему. # BADA55 | Спецификация WHATWG HTML содержит точный алгоритм анализа устаревшего цвета.значение: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Код Netscape Classic, используемый для анализа цветовых строк, имеет открытый исходный код: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Например, обратите внимание, что каждый символ анализируется как шестнадцатеричная цифра, а затем переводится в 32-разрядное целое число без проверки переполнения. В 32-битное целое число помещается только восемь шестнадцатеричных цифр, поэтому учитываются только последние 8 символов. После разбора шестнадцатеричных цифр на 32-битные целые числа они затем усекаются до 8-битных целых чисел путем деления их на 16, пока они не умещаются в 8-битные, поэтому ведущие нули игнорируются. Обновление: этот код не совсем соответствует тому, что определено в спецификации, но единственное отличие состоит в нескольких строках кода. Я думаю, что были добавлены следующие строки (в Netscape 4): если (bytes_per_val> 4) { bytes_per_val = 4; } | Ответ: Браузер попытается преобразовать чакноррис в шестнадцатеричное значение. Поскольку c - единственный допустимый шестнадцатеричный символ в chucknorris, значение превращается в: c00c00000000 (0 для всех значений, которые были недопустимыми). Затем браузер делит результат на 3 группы: красный = c00c, зеленый = 0000, синий = 0000. Поскольку допустимые шестнадцатеричные значения для фона html содержат только 2 цифры для каждого типа цвета (r, g, b), последние 2 цифры из каждой группы усекаются, оставляя значение rgb c00000, которое является кирпично-красноватым цветом. | chucknorris начинается с c, и браузер считывает его в шестнадцатеричном виде. Потому что A, B, C, D, E и F - это символы в шестнадцатеричном формате. Браузер преобразует чакноррис в шестнадцатеричное значение C00C00000000. Затем шестнадцатеричное значение C00C00000000 преобразуется в формат RGB (делится на 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Браузеру нужно всего две цифры для обозначения цвета: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Наконец, покажите в веб-браузере bgcolor = C00000. Вот пример, демонстрирующий это: <таблица>| Правила синтаксического анализа цветов устаревших атрибутов включают дополнительные шаги, чем те, которые упомянуты в существующих ответах. Компонент усечения до 2-значной части описывается как: Отменить все символы, кроме последних 8 Отбрасывать ведущие нули один за другим, пока все компоненты имеют ведущий ноль Отбросить все символы, кроме первых 2 Некоторые примеры: oooFoooFoooF 000F 000F 000F <- заменить, заполнить и кусок 0F 0F 0F <- начальные нули усечены 0F 0F 0F <- усечено до 2 символов справа oooFooFFoFFF 000F 00FF 0FFF <- заменить, заполнить и кусок 00F 0FF FFF <- начальные нули усечены 00 0F FF <- усечено до 2 символов справа ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- заменить, заполнить и блокировать BC000000 BC000000 BC000000 <- усечено до 8 символов слева BC BC BC <- усечено до 2 символов справа AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- заменить, заполнить и блокировать 0C000000 0C000000 0C000000 <- усечено до 8 символов слева C000000 C000000 C000000 <- усеченные ведущие нули C0 C0 C0 <- усечено до 2 символов справа Ниже представлена частичная реализация алгоритма. Он не обрабатывает ошибки или случаи, когда пользователь вводит допустимый цвет. function parseColor (input) { // задача: вернуть ошибку, если введено "" input = input.trim (); // задача: вернуть ошибку, если ввод "прозрачный" // задача: вернуть соответствующий #rrggbb, если введен именованный цвет // задача: вернуть #rrggbb, если ввод соответствует #rgb // задача: заменить кодовые точки Unicode, превышающие U + FFFF, на 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { ввод + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); б = б. срез (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# input"). on ("change", function () { var input = $ (это) .val (); var color = parseColor (ввод); var $ cells = $ ("# результат tbody td"); $ Cells.eq (0) .attr ("bgcolor", ввод); $ Cells.eq (1) .attr ("bgcolor", цвет); варзначение: https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-a-legacy-colour-value. Код Netscape Classic, используемый для анализа цветовых строк, имеет открытый исходный код: https://dxr.mozilla.org/classic/source/lib/layout/layimage.c#155. Например, обратите внимание, что каждый символ анализируется как шестнадцатеричная цифра, а затем переводится в 32-разрядное целое число без проверки переполнения. В 32-битное целое число помещается только восемь шестнадцатеричных цифр, поэтому учитываются только последние 8 символов. После разбора шестнадцатеричных цифр на 32-битные целые числа они затем усекаются до 8-битных целых чисел путем деления их на 16, пока они не умещаются в 8-битные, поэтому ведущие нули игнорируются. Обновление: этот код не совсем соответствует тому, что определено в спецификации, но единственное отличие состоит в нескольких строках кода. Я думаю, что были добавлены следующие строки (в Netscape 4): если (bytes_per_val> 4) { bytes_per_val = 4; } | Ответ: Браузер попытается преобразовать чакноррис в шестнадцатеричное значение. Поскольку c - единственный допустимый шестнадцатеричный символ в chucknorris, значение превращается в: c00c00000000 (0 для всех значений, которые были недопустимыми). Затем браузер делит результат на 3 группы: красный = c00c, зеленый = 0000, синий = 0000. Поскольку допустимые шестнадцатеричные значения для фона html содержат только 2 цифры для каждого типа цвета (r, g, b), последние 2 цифры из каждой группы усекаются, оставляя значение rgb c00000, которое является кирпично-красноватым цветом. | chucknorris начинается с c, и браузер считывает его в шестнадцатеричном виде. Потому что A, B, C, D, E и F - это символы в шестнадцатеричном формате. Браузер преобразует чакноррис в шестнадцатеричное значение C00C00000000. Затем шестнадцатеричное значение C00C00000000 преобразуется в формат RGB (делится на 3): C00C00000000 ⇒ R: C00C, G: 0000, B: 0000 Браузеру нужно всего две цифры для обозначения цвета: R: C00C, G: 0000, B: 0000 ⇒ R: C0, G: 00, B: 00 ⇒ C00000 Наконец, покажите в веб-браузере bgcolor = C00000. Вот пример, демонстрирующий это: <таблица> chucknorris c00c00000000 c00000 | Правила синтаксического анализа цветов устаревших атрибутов включают дополнительные шаги, чем те, которые упомянуты в существующих ответах. Компонент усечения до 2-значной части описывается как: Отменить все символы, кроме последних 8 Отбрасывать ведущие нули один за другим, пока все компоненты имеют ведущий ноль Отбросить все символы, кроме первых 2 Некоторые примеры: oooFoooFoooF 000F 000F 000F <- заменить, заполнить и кусок 0F 0F 0F <- начальные нули усечены 0F 0F 0F <- усечено до 2 символов справа oooFooFFoFFF 000F 00FF 0FFF <- заменить, заполнить и кусок 00F 0FF FFF <- начальные нули усечены 00 0F FF <- усечено до 2 символов справа ABCooooooABCooooooABCoooooo ABC000000 ABC000000 ABC000000 <- заменить, заполнить и блокировать BC000000 BC000000 BC000000 <- усечено до 8 символов слева BC BC BC <- усечено до 2 символов справа AoCooooooAoCooooooAoCoooooo A0C000000 A0C000000 A0C000000 <- заменить, заполнить и блокировать 0C000000 0C000000 0C000000 <- усечено до 8 символов слева C000000 C000000 C000000 <- усеченные ведущие нули C0 C0 C0 <- усечено до 2 символов справа Ниже представлена частичная реализация алгоритма. Он не обрабатывает ошибки или случаи, когда пользователь вводит допустимый цвет. function parseColor (input) { // задача: вернуть ошибку, если введено "" input = input.trim (); // задача: вернуть ошибку, если ввод "прозрачный" // задача: вернуть соответствующий #rrggbb, если введен именованный цвет // задача: вернуть #rrggbb, если ввод соответствует #rgb // задача: заменить кодовые точки Unicode, превышающие U + FFFF, на 00 if (input.length> 128) { input = input.slice (0, 128); } if (input.charAt (0) === "#") { input = input.slice (1); } input = input.replace (/ [^ 0-9A-Fa-f] / g, "0"); while (input.length === 0 || input.length% 3> 0) { ввод + = "0"; } var r = input.slice (0, input.length / 3); var g = input.slice (input.length / 3, input.length * 2/3); var b = input.slice (input.length * 2/3); if (r.length> 8) { r = r.slice (-8); g = g.slice (-8); b = b.slice (-8); } while (r.length> 2 && r.charAt (0) === "0" && g.charAt (0) === "0" && b.charAt (0) === "0") { r = r.slice (1); g = g.slice (1); б = б. срез (1); } if (r.length> 2) { r = r.slice (0, 2); g = g.slice (0, 2); b = b.slice (0, 2); } return "#" + r.padStart (2, "0") + g.padStart (2, "0") + b.padStart (2, "0"); } $ (function () { $ ("# input"). on ("change", function () { var input = $ (это) .val (); var color = parseColor (ввод); var $ cells = $ ("# результат tbody td"); $ Cells.eq (0) .attr ("bgcolor", ввод); $ Cells.eq (1) .attr ("bgcolor", цвет); вар chucknorris c00c00000000 c00000